package cn.jbolt.core.enjoy.directive;

import com.jfinal.kit.StrKit;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;

import java.io.IOException;

/**
 * Boolean值转字符串指令 boolToStr
 *
 * @ClassName: BooleanToStrDirective
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2021年2月16日17:41:48
 */
public class BooleanToStrDirective extends Directive {
	private static final String TRUE_DEFAULT_TEXT = "是";
	private static final String FALSE_DEFAULT_TEXT = "否";
	private static final String ENABLE_TRUE_DEFAULT_TEXT = "启用";
	private static final String ENABLE_FALSE_DEFAULT_TEXT = "禁用";
	private Expr valueExpr;
	private Expr trueTextExpr;
	private Expr falseTextExpr;
	private int paraNum;
	private String directiveName;

	public BooleanToStrDirective() {
		this("boolToStr");
	}

	public BooleanToStrDirective(String directiveName) {
		this.directiveName = directiveName;
	}
	@Override
	public void setExprList(ExprList exprList) {
		this.paraNum = exprList.length();
		if (paraNum == 0) {
			throw new ParseException(
					"Wrong number parameter of #" + directiveName + " directive, one parameters at least", location);
		} else if (paraNum == 1) {
			this.valueExpr = exprList.getExpr(0);
		} else if (paraNum == 3) {
			this.valueExpr = exprList.getExpr(0);
			this.trueTextExpr = exprList.getExpr(1);
			this.falseTextExpr = exprList.getExpr(2);
			if (valueExpr == null || (trueTextExpr != null && falseTextExpr == null)
					|| (trueTextExpr == null && falseTextExpr != null)) {
				throw new ParseException("Wrong number parameter of #" + directiveName
						+ " directive, one parameters at least and three parameters at most", location);
			}
		} else {
			throw new ParseException("Wrong number parameter of #" + directiveName
					+ " directive, one parameters at least and three parameters at most", location);
		}
	}

	/**
	 * 输出默认最后text
	 *
	 * @param writer
	 * @param value
	 */
	private void outDefaultText(Writer writer, boolean value) {
		switch (directiveName) {
		case "enable":
			outText(writer, value, ENABLE_TRUE_DEFAULT_TEXT, ENABLE_FALSE_DEFAULT_TEXT);
			break;
		case "boolToStr":
			outText(writer, value, TRUE_DEFAULT_TEXT, FALSE_DEFAULT_TEXT);
			break;
		default:
			outText(writer, value, TRUE_DEFAULT_TEXT, FALSE_DEFAULT_TEXT);
			break;
		}
	}

	/**
	 * 输出最后text
	 *
	 * @param writer
	 * @param value
	 * @param trueText
	 * @param falseText
	 */
	private void outText(Writer writer, boolean value, String trueText, String falseText) {
		try {
			writer.write(value ? trueText : falseText);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		if (valueExpr == null) {
			valueExpr = new Expr() {
				@Override
				public Object eval(Scope scope) {
					return false;
				}
			};
		}
		Object valueObj = this.valueExpr.eval(scope);
		if (valueObj == null) {
			outDefaultText(writer, false);
		} else {
			boolean value = Boolean.parseBoolean(valueObj.toString());
			if (paraNum == 1 || paraNum != 3) {
				outDefaultText(writer, value);
			} else {
				Object trueTextObj = trueTextExpr.eval(scope);
				Object falseTextObj = falseTextExpr.eval(scope);
				if (trueTextObj == null || falseTextObj == null) {
					outDefaultText(writer, value);
				} else {
					String trueText = trueTextObj.toString();
					String falseText = falseTextObj.toString();
					if (StrKit.isBlank(trueText) || StrKit.isBlank(falseText)) {
						outDefaultText(writer, value);
					} else {
						outText(writer, value, trueText, falseText);
					}
				}
			}
		}

	}

	public String getDirectiveName() {
		return directiveName;
	}

	public void setDirectiveName(String directiveName) {
		this.directiveName = directiveName;
	}

}
